package cn.iocoder.yudao.module.ai.utils;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

@Slf4j
@Component
public class DockerClient {


    private static final String IMAGE_NAME = "jupyter:v1.0"; // 镜像名称
    private static final String CONTAINER_NAME = "jupyter_6"; // 容器名称

    @Value("${jupyter.container}")
    private String DOCKER_API_URL;// = "http://8.147.234.160:7375/containers";



    /**
     * 创建并启动容器
     * @param port
     * @param workPath
     * @return
     */
    public String createAndRunDocker(String port,String workPath){
        //构建镜像地址
         String DOCKER_API_URL_CREATE = DOCKER_API_URL + "/create";
        //启动镜像地址
         String DOCKER_API_URL_START = DOCKER_API_URL + "/%s/start";
        try {
            // 创建容器的请求体
            JSONObject createConfig = new JSONObject();
            createConfig.put("Image", IMAGE_NAME);
            createConfig.put("Name", CONTAINER_NAME);

            JSONObject hostConfig = new JSONObject();
            JSONObject portBindings = new JSONObject();
            JSONObject portBinding = new JSONObject();
            portBinding.put("HostPort", port);
            portBindings.put("8888/tcp", new JSONArray().put(portBinding));
            hostConfig.put("PortBindings", portBindings);

            JSONArray binds = new JSONArray();
            binds.put(workPath + ":/home/jovyan");
            hostConfig.put("Binds", binds);

            JSONArray env = new JSONArray();
            env.put("JUPYTER_TOKEN='1234'");
            hostConfig.put("Env", env);

            createConfig.put("HostConfig", hostConfig);

            // 发送创建容器的请求
            URL createUrl = new URL(DOCKER_API_URL_CREATE);
            HttpURLConnection createConn = (HttpURLConnection) createUrl.openConnection();
            createConn.setRequestMethod("POST");
            createConn.setRequestProperty("Content-Type", "application/json");
            createConn.setDoOutput(true);


            try (OutputStream os = createConn.getOutputStream()) {
                byte[] input = com.alibaba.fastjson.JSONObject.toJSONString(createConfig).getBytes(StandardCharsets.UTF_8);
                os.write(input, 0, input.length);
            }

            int createResponseCode = createConn.getResponseCode();
            if (createResponseCode != HttpURLConnection.HTTP_CREATED) {
                throw new RuntimeException("Failed to create container. Response code: " + createResponseCode);
            }

            // 从响应体中获取容器ID（这里省略了实际解析响应体的代码）
            // 读取响应
            int responseCode = createConn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_CREATED) {
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(createConn.getInputStream(), "utf-8"))) {
                    StringBuilder response = new StringBuilder();
                    String responseLine;
                    while ((responseLine = br.readLine()) != null) {
                        response.append(responseLine.trim());
                    }

                    // 解析响应体中的容器ID
                    JSONObject responseJson = new JSONObject(response.toString());
                    String containerId = responseJson.getStr("Id");
                    System.out.println("Created container with ID: " + containerId);


                    // 启动容器的请求
                    URL startUrl = new URL(String.format(DOCKER_API_URL_START, containerId));
                    HttpURLConnection startConn = (HttpURLConnection) startUrl.openConnection();
                    startConn.setRequestMethod("POST");

                    int startResponseCode = startConn.getResponseCode();
                    if (startResponseCode != HttpURLConnection.HTTP_NO_CONTENT) {
                        throw new RuntimeException("Failed to start container. Response code: " + startResponseCode);
                    }
                    log.info("Container created and started successfully.");
                    return containerId;
                }
            } else {
                log.info("Failed to create container. Response code: " + responseCode);
                throw new RuntimeException("Failed to start container. Response code: " + responseCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "errorId";
    }

    public  boolean isContainerRunning(String containerId) {
        String url = DOCKER_API_URL +"/"+ containerId + "/json";
        HttpRequest request = HttpUtil.createGet(url);
        HttpResponse response = request.execute();

        // 检查HTTP响应状态码
        if (!response.isOk()) {
            log.info("Failed to get container info: HTTP response code " + response.getStatus());
            return false;
        }

        // 解析JSON响应
        String responseBody = response.body();
        JSONObject jsonObject = JSONUtil.parseObj(responseBody);

        // 检查容器状态
        JSONObject stateObject = (JSONObject) jsonObject.getObj("State");
        if (stateObject != null) {
            String status = stateObject.getStr("Status");
            return "running".equals(status);
        } else {
            log.info("Failed to parse container state from response");
            return false;
        }
    }


    public  void stopAndRemoveContainer(String containerId) {
        try {
            // 停止容器
            stopContainer(containerId);

            // 删除容器（通常需要先停止容器）
            removeContainer(containerId);

            log.info("Container " + containerId + " stopped and removed successfully.");
        } catch (Exception e) {
            e.printStackTrace();
            log.info("Failed to stop and remove container " + containerId);
        }
    }

    private void stopContainer(String containerId) throws Exception {
        URL url = new URL(DOCKER_API_URL +"/"+ containerId + "/stop");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setDoOutput(true);

        try (OutputStream os = connection.getOutputStream()) {
            // 对于停止容器，通常不需要在请求体中发送任何数据
        }

        int responseCode = connection.getResponseCode();
        if (responseCode != 204) { // 204 No Content 表示成功停止容器
            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                String response = br.readLine();
                log.info("Failed to stop container: " + response);
            }
        }

        connection.disconnect();
    }

    private void removeContainer(String containerId) throws Exception {
        URL url = new URL(DOCKER_API_URL  +"/"+ containerId);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("DELETE");

        int responseCode = connection.getResponseCode();
        if (responseCode != 204) { // 204 No Content 表示成功删除容器
            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                String response = br.readLine();
                log.info("Failed to remove container: " + response);
            }
        }

        connection.disconnect();
    }

    public static void main(String[] args) {
        new DockerClient().createAndRunDocker("7243","/home/jypyter/workpath/727c17ff-75ae-41a3-b0e8-c874f1858ba7");
    }

}